/**
 * @description 基于uview的http模块进行封装的请求模块
 * @author yinzhi
 * @date 2025-03-03
 */
// 引入拦截器配置
import { requestInterceptors, responseInterceptors } from './interceptors.js'
// 引入luch-request
import { http } from '@/uni_modules/uview-plus'
// 引入网络请求基础地址
import { getBaseUrl } from '@/libs/common/baseUrl.js'

// 默认配置常量（全大写命名）
const DEFAULT_CONFIG = {
    baseURL: getBaseUrl(), // 请求根地址
    dataType: 'json', // 返回值类型
    header: {
        'content-type': 'application/json' // 请求头类型
    },
    timeout: 60000, // 请求超时时间
    // 新增配置项
    retryCount: 1, // 请求重试次数
    retryDelay: 1000, // 重试延迟时间
    withCredentials: true // 是否携带凭证
}

// 初始化请求配置
const initRequest = vm => {
    http.setConfig(defaultConfig => {
        return DEFAULT_CONFIG
    })
    // 2. 注册拦截器
    requestInterceptors(vm) // 注册请求拦截器
    responseInterceptors(vm) // 注册响应拦截器
    // 3. 全局错误处理增强
    http.interceptors.response.use(
        response => response, // 直接返回响应
        error => {
            // 统一错误处理
            handleGlobalError(error) // 处理错误
            return Promise.reject(error) // 返回错误
        }
    )

    // 4. 扩展请求方法
    extendHttpMethods() // 扩展http请求方法
}

// 全局错误处理函数
const handleGlobalError = error => {
    const errorMap = {
        timeout: '请求超时，请检查网络连接', // 超时错误提示
        network: '网络异常，请检查网络连接', // 网络错误提示
        server: '服务器开小差了，请稍后再试' // 服务器错误提示
    }

    // 判断错误类型
    const errorType =
        error.message && error.message.includes('timeout')
            ? 'timeout'
            : error.message && error.message.includes('Network Error')
            ? 'network'
            : 'server'

    uni.showToast({
        title: errorMap[errorType], // 显示对应的错误提示
        icon: 'none',
        duration: 2000 // 提示持续时间
    })
}

// 扩展自定义方法
const extendHttpMethods = () => {
    // 带自动重试的请求
    http.retryRequest = async config => {
        let retry = config.retryCount || DEFAULT_CONFIG.retryCount // 获取重试次数
        while (retry > 0) {
            try {
                return await http.request(config) // 尝试请求
            } catch (err) {
                if (--retry === 0) throw err // 如果重试次数用尽，抛出错误
                await new Promise(
                    resolve => setTimeout(resolve, config.retryDelay || DEFAULT_CONFIG.retryDelay) // 等待重试延迟
                )
            }
        }
    }

    // 支持AbortController的请求
    http.createAbortRequest = config => {
        const controller = new AbortController() // 创建AbortController实例
        const requestConfig = {
            ...config,
            signal: controller.signal // 将信号传递给请求配置
        }
        return {
            request: http.request(requestConfig), // 返回请求
            abort: () => controller.abort() // 返回中止请求的方法
        }
    }
}

export { initRequest }
